package com.ciaojian.client.controller;

import cn.hutool.core.collection.CollUtil;
import com.ciaojian.core.constant.RedisConstant;
import com.ciaojian.core.enums.base.IBaseEnum;
import com.ciaojian.core.enums.business.CounterClickTypeEnum;
import com.ciaojian.core.model.ClickCounter;
import com.ciaojian.core.util.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author Atlakyn
 */
@Api(tags = "计数")
@RestController
@Slf4j
@RequestMapping("/counter")
public class CounterController {
    @Resource
    private RedisTemplate<String, ClickCounter> redisTemplate;

    /**
     * 先存进 Redis,每天晚上定时写入数据库
     *
     * @see com.ciaojian.timer.task.ClickMallCounterScheduled
     */
    @ApiOperation("统计点击次数")
    @PostMapping("/clicks")
    public Result clickRateCounter(Integer type) {
        try {
            CounterClickTypeEnum typeEnum = IBaseEnum.valueOf(CounterClickTypeEnum.class, type);
            Assert.notNull(typeEnum, "类别有误");

            String key = RedisConstant.COUNTER_CLICK.concat(typeEnum.getRedisKey());
            redisTemplate.execute(new SessionCallback<Object>() {
                @Override
                public <K, V> Object execute(RedisOperations<K, V> operations) throws DataAccessException {
                    List<Object> result;
                    do {
                        redisTemplate.watch(key);
                        // 计数器
                        ClickCounter counter = redisTemplate.opsForValue().get(key);
                        if (counter == null) {
                            counter = new ClickCounter();
                            counter.setCount(0);
                            counter.setType(typeEnum);
                        }
                        counter.setCount(counter.getCount() + 1);
                        redisTemplate.opsForValue().set(key, counter);
                        redisTemplate.multi();
                        result = redisTemplate.exec();
                    } while (CollUtil.isNotEmpty(result));
                    // 跳出函数
                    return null;
                }
            });
        }catch (Exception e){
            log.info("统计点击次数异常"+e.getMessage());
        }
        return Result.ok();
    }
}
